# coding=utf-8
"""
作者：董新强 
创建时间：2020.12.07
描述：提供对外服务
"""
from tornado.gen import coroutine

from base_handler import BaseHandler
from framework.log_util import log_async
from framework.msg import failure
from framework.redis_helper import ReidsHelper
from framework.utilities import to_string, to_list, to_int, get_len
from pools import run_async
from services.applications.answer_manage import AnswerManage
from services.applications.application_manage import ApplicationManage
from services.applications.score_manage import ScoreManage


class LoginHandler(BaseHandler):
    @coroutine
    def post(self, *args, **kwargs):
        try:
            key, randstr, sha = self.req_dict('id'), self.req_dict('randstr'), self.req_dict('key')
            if get_len(key) != 32 or get_len(sha) != 64 or get_len(randstr) != 12: return failure(msg='参数错误')
            result = yield run_async(ApplicationManage.login, key, randstr, sha, self.get_client_ip())
            self.to_reponse(self, result)
        except Exception as e:
            dic = {'id': self.get_client_ip()}
            dic.update(self.req_dict())
            yield log_async(e, 'login', dic)
            self.to_reponse(self, failure(msg='登录失败'))


class StartTestHandler(BaseHandler):
    @coroutine
    def post(self, *args, **kwargs):
        try:
            result = yield run_async(AnswerManage(self.appid, test_id=0).start_test, self.req_dict())
            self.to_reponse(self, result)
        except Exception as e:
            dic = {'ip': self.get_client_ip()}
            dic.update(self.req_dict())
            yield log_async(e, 'StartTestHandler', dic)
            self.to_reponse(self, failure(msg='创建测试失败'))


class TestHandler(BaseHandler):
    @coroutine
    def post(self):
        """答题"""
        if not self.validated: return self.finish(failure(msg='没有权限').responseMsg())
        yield self.do_async_action(('answer',))

    def cache_key(self, test_id):
        return 'cat_app_%d' % (test_id)

    async def _get_pre_answers(self, cache, test_id):
        answers = await cache.get(self.cache_key(test_id))
        return to_list(answers)

    async def _update_cache_ansers(self, cache, test_id, answer_info_ls):
        await cache.set(self.cache_key(test_id), to_string(answer_info_ls))

    async def _delete_cache_answers(self, cache, test_id):
        await cache.delete(self.cache_key(test_id))

    async def answer(self):
        # 答题
        test_id = to_int(self.req_dict('tid'))  # 测试ID
        if not test_id: return failure(msg='参数错误')

        cache = ReidsHelper()  # 初始化缓存
        try:
            pre_answers = await self._get_pre_answers(cache, test_id=test_id)  # 从缓存中获取答案

            # 答题
            result = await run_async(AnswerManage(self.appid, test_id, selector='difficult', pre_answers=pre_answers).to_answer, self.req_dict())
            if result.is_ok():
                if 'answers' in result.data:  # 更新缓存
                    await self._update_cache_ansers(cache, test_id=test_id, answer_info_ls=result.data.pop('answers'))
                elif 'finished' in result.data:
                    await self._delete_cache_answers(cache, test_id)

            return result
        except Exception as e:
            await log_async(e, 'TestHandler.post.answer(appid={})'.format(self.appid), self.req_dict())
            return failure(msg='服务器内部错误')
        finally:
            cache.close()


class ScoreHandler(BaseHandler):
    @coroutine
    def get(self, *args, **kwargs):
        try:
            result = yield run_async(ScoreManage(self.appid).get_score, self.req_dict('tid', int))
            self.to_reponse(self, result)
        except Exception as e:
            dic = {'ip': self.get_client_ip()}
            dic.update(self.req_dict())
            yield log_async(e, 'ScoreHandler', dic)
            self.to_reponse(self, failure(msg='获取得分失败'))
